package fixture;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.io.IOUtils;

public class FixtureBuilder {

	private final FixtureFinder fixtureFinder = new FixtureFinder();

	public <T> T getBaseFixture(Class<T> objectType)
			throws InstantiationException, IllegalAccessException, IOException,
			SecurityException, NoSuchFieldException, NoSuchMethodException,
			IllegalArgumentException, InvocationTargetException {
		String fixtureName = objectType.getSimpleName();
		InputStream input = fixtureFinder.findFixture(fixtureName);
		List<String> lines = IOUtils.readLines(input);
		if (lines.size() == 0 || lines.size() == 1) {
			return null;
		}
		String[] parameterNames = lines.get(0).split(",");
		String[] baseProperties = lines.get(1).split(",");
		if (baseProperties.length != parameterNames.length) {
			return null;
		}
		T ob = objectType.newInstance();
		for (int i = 0; i < parameterNames.length; i++) {
			BeanUtils.setProperty(ob, parameterNames[i], baseProperties[i]);
		}
		return ob;
	}

	public <T> List<T> getAllFixtures(Class<T> objectType)
			throws InstantiationException, IllegalAccessException,
			InvocationTargetException, IOException {
		String fixtureName = objectType.getSimpleName();
		InputStream input = fixtureFinder.findFixture(fixtureName);
		List<String> lines = IOUtils.readLines(input);
		if (lines.size() == 0 || lines.size() == 1) {
			return null;
		}
		String[] parameterNames = lines.remove(0).split(",");
		List<T> objects = new ArrayList<T>();
		for (String line : lines) {
			objects.add(getSingleObject(objectType, line, parameterNames));
		}
		return objects;
	}

	private <T> T getSingleObject(Class<T> objectType, String line,
			String[] parameterNames) throws InstantiationException,
			IllegalAccessException, InvocationTargetException {
		String[] baseProperties = line.split(",");
		if (baseProperties.length != parameterNames.length) {
			return null;
		}
		T ob = objectType.newInstance();
		for (int i = 0; i < parameterNames.length; i++) {
			BeanUtils.setProperty(ob, parameterNames[i], baseProperties[i]);
		}
		return ob;
	}

}
